﻿using InterfaceLib;
using PluginNET;
using PluginNET.events;
using System;

namespace Plugin.NETTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // 使用接口来实例化插件管理器
            // 如果要对其它接口进行插件管理，
            // 那么可以创建另一个插件管理器的实例
            var pluginManager = new PluginManager<PluginInterface>();

            // 处理插件管理器发出的事件
            pluginManager.OnAssemblyLoading += PluginManager_OnAssemblyLoading;
            pluginManager.OnAssemblyLoaded += PluginManager_OnAssemblyLoaded;
            pluginManager.OnError += PluginManager_OnError;
            pluginManager.OnInstanceCreating += PluginManager_OnInstanceCreating;
            pluginManager.OnInstanceCreated += PluginManager_OnInstanceCreated;

            // 加载插件目录下的所有插件
            pluginManager.Load();

            // 开始监视新放进目录的插件
            pluginManager.Watch();


            Console.WriteLine("正在监视插件目录变动，按`Enter`退出");
            Console.ReadLine();
        }

        private static void PluginManager_OnAssemblyLoading(object sender, PluginAssemblyLoadingArgs e)
        {
            Console.WriteLine($"准备从文件\"{e.FileName}\"加载程序集");
        }

        private static void PluginManager_OnAssemblyLoaded(object sender, PluginAssemblyLoadedArgs e)
        {
            Console.WriteLine($"从文件\"{e.FileName}\"加载程序集\"{e.Assembly}\"成功");
        }

        private static void PluginManager_OnInstanceCreating(object sender, PluginInstanceCreatingArgs e)
        {
            Console.WriteLine($"准备从程序集\"{e.Assembly}\"加载类型\"{e.Class}\"");
        }

        private static void PluginManager_OnInstanceCreated(object sender, PluginInstanceCreatedArgs<PluginInterface> e)
        {
            var plugin = e.Instance;
            Console.WriteLine($"从程序集\"{e.Assembly}\"加载类型\"{e.Class}\"成功");
            Console.WriteLine($"插件名称: {plugin.Name}, 版本: {plugin.Version}");
            e.Instance.Load();
            Console.WriteLine("Method1:" + plugin.Method1());
            Console.WriteLine("Method2:" + plugin.Method2("啊呀哟"));
        }

        private static void PluginManager_OnError(object sender, PluginErrorEventArgs e)
        {
            switch (e.ErrorType)
            {
                case PluginNET.error.PluginErrorTypes.None:
                    break;
                case PluginNET.error.PluginErrorTypes.InvalidDll:
                    Console.WriteLine($"文件\"{e.FileName}\"不是有效有dll: {e.Exception}");
                    break;
                case PluginNET.error.PluginErrorTypes.CannotLoadClassTypes:
                    Console.WriteLine($"无法从文件\"{e.FileName}\"中加载类型: {e.Exception}");
                    break;
                case PluginNET.error.PluginErrorTypes.ImplementionClassNotFound:
                    Console.WriteLine($"在文件\"{e.FileName}\"中没有找到实现了指定接口的类");
                    break;
                case PluginNET.error.PluginErrorTypes.IllegalClassDefinition:
                    Console.WriteLine($"在文件\"{e.FileName}\"中找到了实现指定接口的类，但是其声明不是class或声明为abstract或不是public");
                    break;
                case PluginNET.error.PluginErrorTypes.DefaultConstructorNotFound:
                    Console.WriteLine($"在文件\"{e.FileName}\"中找到了实现指定接口的类，但未找到默认的无参构造函数");
                    break;
                case PluginNET.error.PluginErrorTypes.InstanceCreateFailed:
                    Console.WriteLine($"在文件\"{e.FileName}\"中找到了实现指定接口的类\"{e.ClassType}\"，但是创建实例时抛出了异常:{e.Exception}");
                    break;
                case PluginNET.error.PluginErrorTypes.Unkown:
                    Console.WriteLine("未知错误");
                    break;
                default:
                    break;
            }
        }
    }
}
